/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.matching;

import java.util.Hashtable;

import cgl.narada.event.NBEvent;
import cgl.narada.event.TemplateProfileAndSynopsisTypes;
import cgl.narada.matching.integer.ClientIntegerMatching;
import cgl.narada.matching.integer.IntegerProfile;
import cgl.narada.matching.regex.ClientRegExMatching;
import cgl.narada.matching.regex.RegExProfile;
import cgl.narada.matching.string.ClientStringMatching;
import cgl.narada.matching.string.StringProfile;
import cgl.narada.matching.tagvaluepairs.TagValueClientMatching;
import cgl.narada.matching.tagvaluepairs.TagValueProfile;
import cgl.narada.matching.xmlxpath.ClientXPathMatching;
import cgl.narada.matching.xmlxpath.XPathProfile;
import cgl.narada.service.ServiceException;

/** Manages all the matching trees hosted at an entity/service.  
    
    @author Shrideep Pallickara
    $Revision$
    $Date$
*/

public class EntityProfileMatchingTrees {
  private Hashtable profiles;
  
  private ClientStringMatching stringMatching;
  private ClientIntegerMatching integerMatching;
  private ClientXPathMatching xpathMatching;
  private ClientRegExMatching regexMatching;
  private TagValueClientMatching tagValueMatching;
  private String moduleName = "EntityProfileMatchingTrees: ";


  public EntityProfileMatchingTrees() {
    stringMatching = new ClientStringMatching(0, 3, null);
    integerMatching = new ClientIntegerMatching(0,3, null);
    xpathMatching = new ClientXPathMatching(0,3, null);
    regexMatching = new ClientRegExMatching(0,3, null);
    tagValueMatching = new TagValueClientMatching(0,3, null);

    profiles = new Hashtable();
  }

  /** This method is used to register/deregister a profile */
  public void 
  manageSubscriptionProfile(Profile profile, boolean addProfile) 
    throws ServiceException {
    Object profileKey = profile.getProfileId();

    if (addProfile) {
      if (profiles.containsKey(profileKey)) {
	throw new ServiceException(moduleName + profile + 
				   " previously registered");
      }
      profiles.put(profileKey, profile);
    } else {
      profiles.remove(profileKey);
    }
    MatchingTree _matchingTree=null;
    int profileType = profile.getProfileType();

    if (profileType == TemplateProfileAndSynopsisTypes.STRING) {
      _matchingTree = (MatchingTree)stringMatching;
    }

    if (profileType == TemplateProfileAndSynopsisTypes.INTEGER) {
      _matchingTree = (MatchingTree)integerMatching;
    }

    if (profileType == TemplateProfileAndSynopsisTypes.XML) {
      _matchingTree = (MatchingTree) xpathMatching;
    }

    if (profileType == TemplateProfileAndSynopsisTypes.REGULAR_EXPRESSIONS) {
      _matchingTree = (MatchingTree) regexMatching;
    }
    
    if (profileType == TemplateProfileAndSynopsisTypes.TAG_VALUE_PAIRS) {
      _matchingTree = (MatchingTree) tagValueMatching;
    }
    
    if (_matchingTree == null) {
      System.out.println(moduleName + "Matching tree to manage profile " + 
			 profile + " has not been initialized");
      return;
    }
     
    if (addProfile) {
      _matchingTree.addSubscriptionProfile(profile);
    } else {
      _matchingTree.removeSubscriptionProfile(profile);
    } /*end addProfile*/


  }

  /** This method is used to register/deregister a profile, with an alternate
      consumerId associated with the profile. This is useful for dealing with
      local producers/consumers that have an interest in the profile in 
      question*/
  public void 
  manageSubscriptionProfile(Profile profile, boolean addProfile, 
			    int consumerId) 
    throws ServiceException {
    Profile profileToAdd = null;
    int profileType = profile.getProfileType();
    if (profileType == TemplateProfileAndSynopsisTypes.STRING) {
      profileToAdd = new StringProfile((String)profile.getSubscription(), 
				       consumerId, profile.getProfileId());
    }

    if (profileType == TemplateProfileAndSynopsisTypes.INTEGER) {
      profileToAdd = new IntegerProfile((Integer)profile.getSubscription(), 
					consumerId, profile.getProfileId());
    }
    
    if (profileType == TemplateProfileAndSynopsisTypes.XML) {
      profileToAdd = new XPathProfile((String)profile.getSubscription(), 
				      consumerId, profile.getProfileId());
    }
    
    if (profileType == TemplateProfileAndSynopsisTypes.REGULAR_EXPRESSIONS) {
      profileToAdd = new RegExProfile((String)profile.getSubscription(), 
				      consumerId, profile.getProfileId());
    }
    
    if (profileType == TemplateProfileAndSynopsisTypes.TAG_VALUE_PAIRS) {
      profileToAdd = new TagValueProfile((String)profile.getSubscription(), 
					 consumerId, profile.getProfileId());
    }
    
    if (profileToAdd == null) {
      throw new ServiceException(moduleName + "Unkown profile type [" +
				 profile.getProfileType() + "] specified");
    }
    
    manageSubscriptionProfile(profileToAdd, addProfile);
  }
  
  public Hashtable computeEventDestinations(NBEvent nbEvent) {
    Hashtable dests= null;
    if (nbEvent.getContentSynopsisType() == 
	TemplateProfileAndSynopsisTypes.STRING) {
      dests = (Hashtable) stringMatching.matchEvent(nbEvent);
    }

    if (nbEvent.getContentSynopsisType() == 
	TemplateProfileAndSynopsisTypes.INTEGER) {
      dests = (Hashtable) integerMatching.matchEvent(nbEvent);
    }

    if (nbEvent.getContentSynopsisType() == 
	TemplateProfileAndSynopsisTypes.XML) {
      dests = (Hashtable) xpathMatching.matchEvent(nbEvent);
    }
    
    if (nbEvent.getContentSynopsisType() == 
	TemplateProfileAndSynopsisTypes.REGULAR_EXPRESSIONS) {
      dests = (Hashtable) regexMatching.matchEvent(nbEvent);
    }

    if (nbEvent.getContentSynopsisType() == 
	TemplateProfileAndSynopsisTypes.TAG_VALUE_PAIRS) {
      dests = (Hashtable) tagValueMatching.matchEvent(nbEvent);
    }
    
    return dests;
  }

  
}
